#include "c_array.h"
#include <string.h>
#include <stdio.h>
Array* ConstructArray(unsigned int capacity)
{
    capacity = capacity == 0 ? 10 : capacity;
    Array* array = (Array*)malloc(sizeof(Array));
    array->size = 0;
    array->capacity = capacity;
    array->array = (void**)(malloc(sizeof(void*)*capacity));
    memset((void*)array->array,0,sizeof(void*)*capacity);
    return array;
}

void DestructArray(Array* array)
{
    if(!array) return ;
    array->size = array->capacity = 0;
    free((void*)array->array);
    array->array = NULL;
    free(array);
    array = NULL;
}

bool InitArray(Array* array,unsigned int capacity)
{
    if(!array) return false;
    capacity = capacity == 0 ? 10 : capacity;
    array->size = 0;
    array->capacity = capacity;
    array->array = (void**)(malloc(sizeof(void*)*capacity));
    memset((void*)array->array,0,sizeof(void*)*capacity);
    return true;
}

void ReleaseArray(Array* array)
{
    if(!array) return ;
    array->size = array->capacity = 0;
    free((void*)array->array);
    array->array = NULL;
}

void Insert(Array* array,unsigned int pos,void* data)
{
    if(!array || pos > array->size)
    {
        return ;
    }
    if(array->size >= array->capacity)
    {
        //expand 
        unsigned int new_capacity = array->capacity*2;
        void** new_array = (void**)malloc(sizeof(void*)*new_capacity);
        memcpy((void*)new_array,(void*)array->array,sizeof(void*)*array->capacity);
        free((void*)array->array);
        array->array = new_array;
        array->capacity = new_capacity;       
    }
    for(unsigned int i = array->size; i>pos; --i)
    {
        array->array[i] = array->array[i-1];
    }
    array->array[pos] = data;
    ++array->size;
}

void PushBack(Array* array,void* data)
{
    Insert(array,array->size,data);
}

void PushFront(Array* array,void* data)
{
    Insert(array,0,data);
}

void Erase(Array* array,unsigned int pos)
{
    if(!array || array->size == 0 || pos > array->size) return ;
    for(unsigned int i=pos; i<array->size-1; ++i)
    {
        array->array[i] = array->array[i+1];
    }
    --array->size;
}

void PopBack(Array* array)
{
    Erase(array,array->size);
}

void PopFront(Array* array)
{
    Erase(array,0);
}

void* Front(Array* array)
{
    if(!array || array->size == 0) return NULL;
    return array->array[0];
}

void* Back(Array* array)
{
    if(!array || array->size == 0) return NULL;
    return array->array[array->size-1];
}

unsigned int Length(Array* array)
{
    return array->size;
}

unsigned int Capacity(Array* array)
{
    return array->capacity;
}

bool Empty(Array* array)
{
    return array->size == 0;
}

void Clear(Array* array)
{
    array->size = 0;
}

void* At(Array* array,unsigned int pos)
{
    if(!array || pos >= array->size) return NULL;
    return array->array[pos];
}